package com.weimob.mcloud.wechatwork.customer.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * Create Time: 2021年01月21日 13:01
 *
 * @author maosheng.li
 **/
@Configuration
public class ThreadPoolConfig {

    private static final Integer CUP_SIZE = Runtime.getRuntime().availableProcessors();

    @Value("${customer.relation.change.process.pool.core.pool.size:10}")
    Integer corePoolSize;

    @Value("${customer.relation.change.process.pool.max.pool.size:20}")
    Integer maxPoolSize;

    @Value("${customer.relation.change.process.pool.queue.size:5000}")
    Integer queueSize;

    @Bean(name = "commonThreadPool")
    public ThreadPoolTaskExecutor commonThreadPool() {
        return createThreadPoolTaskExecutor(5, 10, 200, "commonThreadPool-");
    }


    private ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int corePoolSize, int maxPoolSize, String threadNamePrefix) {
        return createThreadPoolTaskExecutor(corePoolSize, maxPoolSize, 1000, threadNamePrefix);
    }

    private ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int corePoolSize, int maxPoolSize, Integer queueSize, String threadNamePrefix) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setKeepAliveSeconds(4);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueSize);
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.setAllowCoreThreadTimeOut(true);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    /**
     * 处理外部联系人新增回调的artimes
     *
     * @return
     */
    @Bean(name = "changeCorpExternaluserThreadPool")
    public ThreadPoolTaskExecutor changeCorpExternaluserThreadPool() {
        return createThreadPoolTaskExecutor(5, 5, 100, "changeCorpExternaluserThreadPool-");
    }


    /**
     * 处理客户流程线程池
     *
     * @return
     */
    @Bean(name = "customerProcessThreadPool")
    public ThreadPoolTaskExecutor customerProcessThreadPool() {
        return createThreadPoolTaskExecutor(4, 8, 100, "customerProcessThreadPool-");
    }

    /**
     * 外部联系人消息二阶段处理
     *
     * @return
     */
    @Bean(name = "secondCorpExternaluserThreadPool")
    public ThreadPoolTaskExecutor secondCorpExternaluserThreadPool() {
        return createThreadPoolTaskExecutor(4, 4, 100, "secondCorpExternaluserThreadPool-");
    }

    /**
     * 外部联系人消息二阶段处理（历史）
     *
     * @return
     */
    @Bean(name = "historySecondCorpExternaluserThreadPool")
    public ThreadPoolTaskExecutor historySecondCorpExternaluserThreadPool() {
        return createThreadPoolTaskExecutor(4, 4, 100, "secondCorpExternaluserThreadPool-");
    }


    @Bean(name = "statisticThreadPool")
    public ThreadPoolTaskExecutor statisticThreadPool() {
        return createThreadPoolTaskExecutor(5, 20, "statisticThreadPool-");
    }


    @Bean(name = "queryUserTagThreadPool")
    public ThreadPoolTaskExecutor queryUserTagThreadPool() {
        return createThreadPoolTaskExecutor(100, 100, 200, "queryUserTagThreadPool-");
    }


    /**
     * 处理客户群变更
     */
    @Bean(name = "customerGroupUpdateThreadPool")
    public ThreadPoolTaskExecutor customerGroupUpdateThreadPool() {
        return createThreadPoolTaskExecutor(10, 10, 100, "customerGroupUpdateThreadPool-");
    }

    /**
     * 渠道绑定时-初始化群数据
     */
    @Bean(name = "customerGroupInitialThreadPool")
    public ThreadPoolTaskExecutor customerGroupInitialThreadPool() {
        return createThreadPoolTaskExecutor(5, 10, 200, "customerGroupInitialThreadPool-");
    }

    /**
     * 查询客户列表
     */
    @Bean(name = "queryCustomerThreadPool")
    public ThreadPoolTaskExecutor queryCustomerThreadPool() {
        return createThreadPoolTaskExecutor(100, 100, 500, "queryCustomerThreadPool-");
    }

    /**
     * 导出客户列表
     */
    @Bean(name = "exportCustomerThreadPool")
    public ThreadPoolTaskExecutor exportCustomerThreadPool() {
        return createThreadPoolTaskExecutor(100, 100, 200, "exportCustomerThreadPool-");
    }

    /**
     * 客户群实时统计线程池
     * @return
     */
    @Bean(name = "customerGroupMemberStatisticThreadPool")
    public ThreadPoolTaskExecutor customerGroupMemberStatisticThreadPool() {
        return createThreadPoolTaskExecutor(10, 10, 10000, "customerGroupMemberStatisticThreadPool-");
    }

    /**
     * 客户群全量同步线程池
     * @return
     */
    @Bean(name = "fullCustomerGroupSyncThreadPool")
    public ThreadPoolTaskExecutor FullCustomerGroupSyncThreadPool() {
        return createThreadPoolTaskExecutor(5, 5, 5000, "fullCustomerGroupSyncThreadPool-");
    }

    /**
     * 客户全量同步es
     * @return
     */
    @Bean(name = "customerFlushSearchThreadPool")
    public ThreadPoolTaskExecutor customerFlushSearchThreadPool() {
        return createThreadPoolTaskExecutor(10, 10, 1000, "fullCustomerGroupSyncThreadPool-");
    }

    /**
     * 客户全量同步es
     * @return
     */
    @Bean(name = "customerFlushSearchThreadPoolNested")
    public ThreadPoolTaskExecutor customerFlushSearchThreadPoolNested() {
        return createThreadPoolTaskExecutor(10, 10, 100, "fullCustomerGroupSyncThreadPool-");
    }

    /**
     * 客户群实时统计线程池
     * @return
     */
    @Bean(name = "customerRelationChangeProcessThreadPool")
    public ThreadPoolTaskExecutor customerRelationChangeProcessThreadPool() {
        return createThreadPoolTaskExecutor(corePoolSize, maxPoolSize, queueSize, "customerRelationChangeProcessThreadPool-");
    }

    /**
     * 客户群同步线程池
     * @return
     */
    @Bean(name = "customerGroupInitThreadPool")
    public ThreadPoolTaskExecutor customerGroupInitThreadPool() {
        return createThreadPoolTaskExecutor(4, 8, 1000, "customerGroupInitThreadPool-");
    }

    /**
     * 新增坐席 异步拉取客户群数据
     *
     * @return
     */
    @Bean(name = "addSeatForGroupThreadPool")
    public ThreadPoolTaskExecutor addSeatForGroupThreadPool() {
        return createThreadPoolTaskExecutor(2, 2, 500, "addSeatForGroupThreadPool-");
    }


    /**
     * 查询客户流失
     */
    @Bean(name = "queryCustomerLoseThreadPool")
    public ThreadPoolTaskExecutor queryCustomerLoseThreadPool() {
        return createThreadPoolTaskExecutor(50, 100, 2000, "queryCustomerLoseThreadPool-");
    }

    /**
     * 客户群成员生成wid
     */
    @Bean(name = "createGroupMemberWidThreadPool")
    public ThreadPoolTaskExecutor createGroupMemberWidThreadPool() {
        return createThreadPoolTaskExecutor(10, 20, 500, "createGroupMemberWidThreadPool-");
    }

    /**
     * 授权范围变更
     */
    @Bean(name = "employeeAuthorizeChangeThreadPool")
    public ThreadPoolTaskExecutor employeeAuthorizeChangeThreadPool() {
        return createThreadPoolTaskExecutor(5, 5, 100, "employeeAuthorizeChangeThreadPool-");
    }

    /**
     * 授权范围变更for客户群
     */
    @Bean(name = "employeeAuthorizeChangeForGroupThreadPool")
    public ThreadPoolTaskExecutor employeeAuthorizeChangeForGroupThreadPool() {
        return createThreadPoolTaskExecutor(5, 5, 100, "employeeAuthorizeChangeForGroupThreadPool-");
    }

    /**
     * 坐席限制
     */
    @Bean(name = "employeeSeatChangeThreadPool")
    public ThreadPoolTaskExecutor employeeSeatChangeThreadPool() {
        return createThreadPoolTaskExecutor(5, 5, 100, "employeeSeatChangeThreadPool-");
    }

    /**
     * 坐席限制for客户群
     */
    @Bean(name = "employeeSeatChangeForGroupThreadPool")
    public ThreadPoolTaskExecutor employeeSeatChangeForGroupThreadPool() {
        return createThreadPoolTaskExecutor(5, 5, 100, "employeeSeatChangeForGroupThreadPool-");
    }

    @Bean(name = "syncCustomerTagToTX")
    public ThreadPoolTaskExecutor syncCustomerTagToTX() {
        return createThreadPoolTaskExecutor(5, 5, 2000, "syncCustomerTagToTX-");
    }

    @Bean(name = "customerGroupQueryThreadPool")
    public ThreadPoolTaskExecutor customerGroupQueryThreadPool() {
        return createThreadPoolTaskExecutor(5, 10, 200, "customerGroupQueryThreadPool-");
    }

    @Bean(name = "deleteCustomerTagByConditionThreadPool")
    public ThreadPoolTaskExecutor deleteCustomerTagByConditionThreadPool() {
        return createThreadPoolTaskExecutor(2, 2, 1000, "deleteCustomerTagByConditionThreadPool-");
    }

    /**
     * 客户群同步向CDP打点异步线程池
     * @return
     */
    @Bean(name = "groupSyncCDPPointThreadPool")
    public ThreadPoolTaskExecutor groupSyncCDPPointThreadPool() {
        return createThreadPoolTaskExecutor(2, 4, 100, "groupSyncCDPPointThreadPool-");
    }


    /**
     * 授权范围/坐席变更受影响客户数大于1000 异步化线程池
     */
    @Bean(name = "employeeAuthChangeSyncThreadPool")
    public ThreadPoolTaskExecutor employeeAuthChangeSyncThreadPool() {
        return createThreadPoolTaskExecutor(2, 4, 20, "employeeSeatChangeThreadPool-");
    }

    @Bean(name = "rateLimitForGroupThreadPool")
    public ThreadPoolTaskExecutor rateLimitForGroupThreadPool() {
        return createThreadPoolTaskExecutor(2, 4, 20, "rateLimitForGroupThreadPool-");
    }
}
